#include "stdafx.h"
#include "TextField.h"

#include "2DUtils.h"
#include "Text.h"

using namespace mgui;

TextField::TextField( const Rect & bounds, Type type )
	: mType(type), mText("text"), mHasFocus(false), mHoldingMouse(false)
{
	setBounds(bounds);
}

const std::string & TextField::getText() const
{
	return mText;
}

float TextField::getFloat() const
{
	return (float)atof(mText.c_str());
}

int TextField::getInt() const
{
	return atoi(mText.c_str());
}

void TextField::setString(const std::string & value)
{
	mText = value;
}

void TextField::setFloat(float value)
{
	char buffer[16];
	sprintf_s<16>(buffer, "%.1f", value);
	mText = buffer;
}

void TextField::setInt(int value)
{
	char buffer[16];
	sprintf_s<16>(buffer, "%d", value);
	mText = buffer;
}

void TextField::drawSelf()
{
	mgfx::Utils2D::drawRect(mBounds.X, mBounds.Y, mBounds.Width, mBounds.Height, XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f));
	if(mHasFocus)
		mgfx::Text2D::draw(mText + "|", mBounds.X, mBounds.Y);
	else
		mgfx::Text2D::draw(mText, mBounds.X, mBounds.Y);
}

bool TextField::processLButtonUpInside( const Point & pt )
{
	mHasFocus = true;

	if(mHoldingMouse)
	{
		mHoldingMouse = false;
		mRootControl->unsetExclusiveInputReceiver(*this);
	}

	return true;
}

bool TextField::processLButtonUpOutside( const Point & pt )
{
	mHasFocus = false;

	if(mHoldingMouse)
	{
		mHoldingMouse = false;
		mRootControl->unsetExclusiveInputReceiver(*this);
		return true;
	}

	return false;
}

bool TextField::processLButtonDownInside(const Point & pt)
{
	mHoldingMouse = true;
	mRootControl->setExclusiveInputReceiver(*this);
	mPrevMousePosition = pt;

	return true;
}

bool TextField::processLButtonDownOutside( const Point & pt )
{
	mHasFocus = false;

	return false;
}

bool TextField::processMouseMovedInside( const Point & pt )
{
	return processMouseMoved(pt);
}

bool TextField::processMouseMovedOutside( const Point & pt )
{
	return processMouseMoved(pt);
}

bool TextField::processKeyPressed( const input::KeyEvent & key )
{
	if(!mHasFocus)
		return false;

	bool textChanged = false;

	if(key.PressedKey == input::KeyEvent::KEY_BACKSPACE && mText.size() > 0)
	{
		mText.pop_back();
		textChanged = true;
	}

	if(key.PressedKey == input::KeyEvent::KEY_CHAR)
	{
		mText.push_back(key.Char);
		textChanged = true;
	}

	if(textChanged)
	{
		TextFieldEventArgs eventArgs;
		//if(mType == TYPE_TEXT) eventArgs.TextValue = getText();
		//else if(mType == TYPE_FLOAT) eventArgs.FloatValue = getFloat();
		//else if(mType == TYPE_INT) eventArgs.IntValue = getInt();
		callListeners(EVENT_TEXT_CHANGED, eventArgs);
	}

	return true;
}

bool TextField::processMouseMoved( const Point & pt )
{
	if(mHoldingMouse && mType == TYPE_FLOAT)
	{
		float diff = (float)pt.X - (float)mPrevMousePosition.X;

		float value = getFloat();
		value += diff * 0.1f;
		setFloat(value);

		TextFieldEventArgs eventArgs;
		//if(mType == TYPE_TEXT) eventArgs.TextValue = getText();
		//else if(mType == TYPE_FLOAT) eventArgs.FloatValue = getFloat();
		//else if(mType == TYPE_INT) eventArgs.IntValue = getInt();
		callListeners(EVENT_TEXT_CHANGED, eventArgs);

		mPrevMousePosition = pt;

		return true;
	}
	return false;
}
